//////////////////////////////////////////////////////////////////
// (c) Copyright 2003- by Jeongnim Kim
//////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////
//   Jeongnim Kim
//   National Center for Supercomputing Applications &
//   Materials Computation Center
//   University of Illinois, Urbana-Champaign
//   Urbana, IL 61801
//   e-mail: jnkim@ncsa.uiuc.edu
//   Tel:    217-244-6319 (NCSA) 217-333-3324 (MCC)
//
// Supported by 
//   National Center for Supercomputing Applications, UIUC
//   Materials Computation Center, UIUC
//////////////////////////////////////////////////////////////////
// -*- C++ -*-
/** @file Timer.h
 * @brief Timer class using boost::timer
 */
#ifndef QMCPLUSPLUS_TIMER_H
#define QMCPLUSPLUS_TIMER_H

#include "Message/OpenMP.h"

namespace APPNAMESPACE  {
#if defined(ENABLE_OPENMP)
  /** Timer using omp_get_wtime 
   */
  struct Timer
  {
    double start_time;
    inline Timer() { start_time=omp_get_wtime();}
    inline void restart() {start_time=omp_get_wtime();}
    inline double elapsed() const {
      return omp_get_wtime()-start_time;
    }
  };
  /*
  const double ticks_per_sec=1.e-6/512.;
  struct Timer
  {
    typedef uint64_t ticks_t;
    ticks_t start_time;
    inline ticks_t getticks()
    {
      ticks_t tbl;
      __asm__ __volatile__ ("mftb %0" : "=r"(tbl));
      return tbl;
    }
    inline Timer() { restart();}
    inline void restart() 
    {
      start_time = getticks();
    }
    inline double elapsed() 
    {
      return static_cast<double>((getticks()-start_time))*ticks_per_sec;
    }
  };
  */

  //
//struct Timer
//{
//  struct timeval tp; 
//  double start_time;
//  inline Timer() { restart();}
//  inline void restart() 
//  {
//    gettimeofday(&tp, NULL);                                    
//    start_time=(double)tp.tv_sec+(1.e-6)*tp.tv_usec;
//  }
//  inline double elapsed() 
//  {
//    gettimeofday(&tp, NULL);                                    
//    return (double)tp.tv_sec+(1.e-6)*tp.tv_usec-start_time;
//  }
//};

#else /* use boost or pooma */
#if defined(HAVE_LIBBOOST)
#include <boost/timer.hpp>
  typedef boost::timer Timer;
#else
#include "Utilities/Clock.h"

  struct Timer: private Pooma::Clock {

    Timer() { }
    inline void restart() { start();}
    inline double elapsed() { 
      stop();
      return cpu_time();
    }
  };
#endif
#endif
}
#endif
